// Framework Namespaces
using System;
using System.Collections.Generic;
using System.Text;

// Project Namespaces
using RNChessBoard;
using RNChessBoardCommonTypes;

// NUnit Namespaces
using NUnit.Framework;

namespace RNChessBoard.RNChessBoardCommonTypes.Tests
{   
    [TestFixture]
    public class FENTranslatorTestFixture
    {
        private const string FEN_START_WHITE = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
        private const string FEN_INVALID_NO_PIECES = "/////// w KQkq - 0 1";
        
        /// <summary>
        /// Array containing the default piece positions and board state.
        /// </summary>
        /// <remarks>
        /// Non-zero numbers correspond to piece types.
        /// </remarks>
        private static readonly int[] START_BOARD_ARRAY = new int[64]
            {
                -4,-2,-3,-5,-6,-3,-2,-4,
                -1,-1,-1,-1,-1,-1,-1,-1,
                0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,
                0,0,0,0,0,0,0,0,
                1,1,1,1,1,1,1,1,
                4,2,3,5,6,3,2,4
            };

        FENTranslator _fenBuilder;

        [SetUp]
        protected virtual void SetUp()
        {
             
        }

        /// <summary>
        /// Test creating a new FENBuilder object.
        /// </summary>
        [Test]
        public void New_DefaultConstructor_NotNull()
        {
            FENTranslator  fen = new FENTranslator ();
            Assert.IsNotNull(fen, "FENBuilder failed to instantiate.");
        }

        [Test]
        public void New_ValidFENString_NotNull()
        {
            FENTranslator  fen = new FENTranslator (FEN_START_WHITE);

            Assert.IsNotNull(fen, "FENBuilder failed to instantiate.");
            Assert.IsTrue(fen.WhiteKingsideCastle, "Initial white king-side castle state is invalid.");
            Assert.IsTrue(fen.WhiteQueensideCastle, "Initial white queen-side castle state is invalid.");
            Assert.IsTrue(fen.BlackKingsideCastle, "Initial black king-side castle state is invalid.");
            Assert.IsTrue(fen.BlackQueensideCastle, "Initial black queen-side castle state is invalid.");

            Assert.AreEqual(1, fen.FullMoveNumber, "Initial full move number is invalid.");
            Assert.AreEqual(0, fen.HalfMoveClock, "Initial half-move number is invalid.");
            Assert.AreEqual(PlayerTurn.White, fen.ActiveColor, "Initial player turn is invalid.");

            Assert.IsNotEmpty(fen.ChessBoardArray, "Initial chessboard array property is invalid.");
            Assert.AreEqual(START_BOARD_ARRAY, fen.ChessBoardArray, "Initial chessboard array state is invalid.");

            Assert.AreEqual("-", fen.EnPassantTargetSquare, "Initial En Passant target square is invalid.");
        }

        [Test]
        public void ToString_ValidStartFEN_Equality()
        {
            FENTranslator  fen = new FENTranslator (FEN_START_WHITE);
            Assert.AreEqual(FEN_START_WHITE, fen.ToString(), "Invalid FEN string was returned.");
        }

        [Test,ExpectedException(typeof(System.FormatException))]
        public void New_BadFENString_NoSpaceDelimiters_FormatException()
        {
            string testFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNRwKQkq-01";
            FENTranslator  fen = new FENTranslator (testFEN);
        }

        [Test, ExpectedException(typeof(System.FormatException))]
        public void New_BadFENString_FourSpaceDelimiters_FormatException()
        {
            string testFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 01";
            FENTranslator  fen = new FENTranslator (testFEN);
        }

        [Test,ExpectedException(typeof(System.FormatException))]
        public void New_BadFENString_SixSpaceDelimiters_FormatException()
        {
            string testFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w  KQkq - 0 1";
            FENTranslator  fen = new FENTranslator (testFEN);
        }

        [Test,ExpectedException(typeof(System.FormatException))]
        public void New_BadFENString_BadBlackRank8_abcdefgh_FormatException()
        {
            string testFEN = "abcdefgh/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
            FENTranslator  fen = new FENTranslator (testFEN);
        }

        [Test, ExpectedException(typeof(System.FormatException))]
        public void New_BadFENString_InvalidRank3_SpaceCount9_FormatException()
        {
            string testFEN = "rnbqkbnr/pppppppp/9/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
            FENTranslator  fen = new FENTranslator (testFEN);
        }

        [Test, ExpectedException(typeof(System.FormatException))]
        public void New_BadFENString_BadBoardDelimiters_FormatException()
        {
            string testFEN = "rnbqkbnr-pppppppp-8-8-8-8-PPPPPPPP-RNBQKBNR w KQkq - 0 1";
            FENTranslator  fen = new FENTranslator (testFEN);
        }

        [Test]
        public void New_ValidFENString_FourBlackPawnsRank2_Normal()
        {
            string testFEN = "rnbqkbnr/p1p1p1p1/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
            FENTranslator  fen = new FENTranslator (testFEN);

            testFEN = "rnbqkbnr/4pppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
            fen = new FENTranslator (testFEN);
        }

        [Test, ExpectedException(typeof(System.FormatException))]
        public void New_BadFENString_Exception()
        {
            FENTranslator  fen = new FENTranslator (FEN_INVALID_NO_PIECES);
        }
    }
}
